package com.lz.dsp.task.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.google.gson.Gson;
import com.lz.ad.common.generic.GenericMapper;
import com.lz.ad.common.generic.GenericServiceImpl;
import com.lz.ad.common.util.AppUtils;
import com.lz.dsp.task.dao.AdSlotDao;
import com.lz.dsp.task.dao.MediaDevDao;
import com.lz.dsp.task.dao.OutdoorsInventoryDao;
import com.lz.dsp.task.dao.UnitDao;
import com.lz.dsp.task.entity.AdSlot;
import com.lz.dsp.task.entity.MediaDev;
import com.lz.dsp.task.entity.OutdoorsInventory;
import com.lz.dsp.task.entity.SspAdSlotRtb;
import com.lz.dsp.task.entity.Unit;
import com.lz.dsp.task.entity.UnitDev;
import com.lz.dsp.task.service.OutdoorsInventoryService;

/**
 * 户外媒体库存
 * 
 * @author chensf
 * @version 1.0
 * @date 2019年7月10日15:33:15
 */
@Service
public class OutdoorsInventoryServiceImpl extends GenericServiceImpl<OutdoorsInventory, Long>
		implements OutdoorsInventoryService {

	@Autowired
	private OutdoorsInventoryDao dao;
	@Autowired
	private UnitDao unitDao;
	@Autowired
	private MediaDevDao mediaDevDao;
	@Autowired
	private AdSlotDao adSlotDao;

	@Override
	protected GenericMapper<OutdoorsInventory, Long> getGenericMapper() {
		return dao;
	}

	public static void main(String[] args) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date());
		cal.add(Calendar.DAY_OF_MONTH, 2);
		int w = cal.get(Calendar.DAY_OF_WEEK);
		System.out.println(w);
	}

	@Override
	public boolean handle(String uuid, UnitDev unitDev) {
		try {
			String unit_no = unitDev.getUnit_no();
			Long dev_id = unitDev.getDev_id();
			MediaDev mediaDev = mediaDevDao.selectOneByPK(dev_id);
			Long ssp_media_id = mediaDev.getSsp_media_id();
			BigDecimal material_width = mediaDev.getScreen_width();
			BigDecimal material_height = mediaDev.getScreen_height();
			Map<String, Object> map = new java.util.HashMap<String, Object>();
			map.put("unit_no", unit_no);
			Unit unit = unitDao.selectOneByMap(map);
			String settlement_type_dtk = unit.getBid_mode_dtk();
			String week_names = unit.getWeek_names();
			String week_ids = week_names.replace("SUN", "1").replace("MON", "2").replace("TUE", "3").replace("WED", "4")
					.replace("THU", "5").replace("FRI", "6").replace("SAT", "7");
			map.clear();
			map.put("ssp_media_id", ssp_media_id);
			if (!"Unlimited".equals(unit.getAdslot_type_dtk())) {
				map.put("adslot_type_dtk", unit.getAdslot_type_dtk());
			}
			if (!"Unlimited".equals(settlement_type_dtk)) {
				map.put("settlement_type_dtk", settlement_type_dtk);
			}
			map.put("show_type", unit.getShow_type());
			map.put("material_width", material_width);
			map.put("material_height", material_height);
			map.put("duration", unit.getDuration());
			logger.debug("searchMap:" + new Gson().toJson(map));
			List<AdSlot> adSlotList = adSlotDao.selectListByMap(map);
			String put_start_time = unit.getPut_start_time();
			String put_stop_time = unit.getPut_stop_time();
			String put_time = put_start_time;
			List<OutdoorsInventory> outdoorsInventory_list_ins = new ArrayList<OutdoorsInventory>();
			while (put_time.compareTo(put_stop_time) <= 0) {
				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(format.parse(put_time));
				String w = calendar.get(Calendar.DAY_OF_WEEK) + "";
				for (AdSlot adSlot : adSlotList) {
					map.clear();
					map.put("play_time", put_time);
					map.put("dev_id", dev_id);
					map.put("ssp_ad_slot_rtb_id", adSlot.getId());
					Long count = dao.selectCountByMap(map);
					if (count <= 0 && week_ids.indexOf(w) >= 0) {
						if (mediaDev.getSsp_media_id() == adSlot.getSsp_media_id()) {
							OutdoorsInventory outdoorsInventory = new OutdoorsInventory();
							outdoorsInventory.setPlay_time(put_time);
							outdoorsInventory.setDev_id(dev_id);
							outdoorsInventory.setSsp_supply_id(mediaDev.getSsp_supply_id());
							outdoorsInventory.setSsp_supply_name(mediaDev.getSsp_supply_name());
							outdoorsInventory.setSsp_res_id(mediaDev.getSsp_res_id());
							outdoorsInventory.setSsp_res_name(mediaDev.getSsp_res_name());
							outdoorsInventory.setSsp_media_id(mediaDev.getSsp_media_id());
							outdoorsInventory.setSsp_ad_slot_rtb_id(adSlot.getId());
							outdoorsInventory.setUdid(mediaDev.getUdid());
							outdoorsInventory.setProvince_code(mediaDev.getProvince_code());
							outdoorsInventory.setProvince_name(mediaDev.getProvince_name());
							outdoorsInventory.setCity_code(mediaDev.getCity_code());
							outdoorsInventory.setCity_name(mediaDev.getCity_name());
							outdoorsInventory.setArea_code(mediaDev.getArea_code());
							outdoorsInventory.setArea_name(mediaDev.getArea_name());
							outdoorsInventory.setPoi_id(mediaDev.getPoi_id());
							outdoorsInventory.setPoi_name(mediaDev.getPos_name());
							outdoorsInventory.setInventory(adSlot.getPromise_flow());
							outdoorsInventory.setOccupy_inventory(0l);
							outdoorsInventory.setLock_inventory(0l);
							outdoorsInventory.setPlay_time(put_time);
							outdoorsInventory_list_ins.add(outdoorsInventory);
						}
					}
				}
				calendar.add(Calendar.DAY_OF_MONTH, 1);
				Date lastDate = calendar.getTime();
				put_time = format.format(lastDate);
			}
			if (outdoorsInventory_list_ins != null && outdoorsInventory_list_ins.size() > 0) {
				dao.insertList(outdoorsInventory_list_ins);
			}
			return true;
		} catch (Exception e) {
			logger.error("Exception={}", ExceptionUtils.getFullStackTrace(e));
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return false;
		}

	}

	@Override
	public boolean update(String uuid, SspAdSlotRtb sspAdSlotRtb) {

		Boolean updateBoolen = false;

		// 根据 广告位id 查询库存表， 并判断承诺流量和库存值大小，进行相关修改操作
		logger.info("uuid:{}, 操作：根据 广告位id 查询库存表， 并判断承诺流量和库存值大小，进行相关修改操作", uuid);
		Map<String, Object> map = new HashMap<String, Object>();
		map.clear();
		map.put("ssp_ad_slot_rtb_id", sspAdSlotRtb.getId());
		List<OutdoorsInventory> dspOutdoorsInventorieList = dao.selectListByMap(map);
		
		logger.info("uuid:{}, 查询符合条件的库存信息, queryMap:{}, dspOutdoorsInventorieList", uuid, map, dspOutdoorsInventorieList);
		
		if (AppUtils.isNotEmpty(dspOutdoorsInventorieList) && dspOutdoorsInventorieList.size() > 0) {
			
			for (OutdoorsInventory dspOutdoorsInventory : dspOutdoorsInventorieList) {

				Long dspOutDoorsInventoryId = dspOutdoorsInventory.getId();
				// 获取库存信息详情
				OutdoorsInventory dspOutdoorsInventoryTemp = dao.selectOneByPK(dspOutDoorsInventoryId);

				Long dspOutDoorsOccupyInventory = dspOutdoorsInventoryTemp.getOccupy_inventory();
				Long dspOutdoorsLockInventory = dspOutdoorsInventoryTemp.getLock_inventory();
				Long dspOutdoorsInventoryValue = dspOutdoorsInventoryTemp.getInventory();

				Long sumValue = dspOutDoorsOccupyInventory + dspOutdoorsLockInventory + dspOutdoorsInventoryValue;
				Long promiseFlowValue = sspAdSlotRtb.getPromise_flow();
				Long newPromiseFlow = dspOutdoorsInventoryValue;

				// 判断承诺流量值是否 变更，如果变更这 变更相关库存值
				logger.info("uuid:{}, 执行操作：判断承诺流量值是否 变更，如果变更这 变更相关库存值, promiseFlowValue:{}, sumValue:{}", uuid,promiseFlowValue);
				if (promiseFlowValue != sumValue) {

					// 承诺流量修改的 大于等于修改之前的。
					if (promiseFlowValue > sumValue) {
						newPromiseFlow = promiseFlowValue - dspOutDoorsOccupyInventory - dspOutdoorsLockInventory;
					} else {
						//判断剩余库存 是否大于  减少的库存
						Long  difPromiseFlowValue = sumValue - promiseFlowValue;
						Long relInventoryValue = dspOutdoorsInventoryValue - difPromiseFlowValue;
						if (relInventoryValue > 0) {
							newPromiseFlow = relInventoryValue;
						} else {
							newPromiseFlow = 0L;
						}
					}
					
					dspOutdoorsInventoryTemp.setInventory(newPromiseFlow);
					
					Integer resultValue = dao.update(dspOutdoorsInventoryTemp);
					if (AppUtils.isNotEmpty(resultValue) && !(resultValue > 0)) {
						return updateBoolen;
					}
				}
			}
		}
		
		return true;
	}

}
